package com.springTxStudy.service;

import com.springTxStudy.dao.StudentDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.FileInputStream;
import java.io.FileNotFoundException;


/*
添加事务@Transactional：
加在方法上：当前方法有事务，会覆盖类上的声明，类上的@Transactional对该方法不再奏效
加在类上：类下的所有方法都有事务
一般声明在类上，查询方法可以添加@Transactional(readOnly=true)来设置成只读模式，提高查询  效率
 */
/*


 */
@Service
@Transactional
public class StudentService {

    @Autowired
    private StudentDao studentDao;

    /*
    timeout属性设置超时时间，单位秒

    rollbackFor指定异常回滚
    norollbackFor在指定异常回滚的基础上，指定其中的异常不回滚
    默认指定发生运行时异常时，事务回滚

    事务隔离
    建议加二级隔离：读已提交。isolation = Isolation.READ_COMMITTED
     */
    @Transactional(timeout = 3, rollbackFor = Exception.class, noRollbackFor = FileNotFoundException.class, isolation = Isolation.READ_COMMITTED)
    public void changeInfo() {
        studentDao.updateNameById(1, "阿Q");
        try {
            Thread.sleep(1000); // 单位毫秒
            new FileInputStream("不存在的文件");
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (FileNotFoundException e) {
            System.out.println(e.getMessage());
        }
        System.out.println("---------------------");
        studentDao.updateAgeById(1, 9);
    }


    /*
    只读模式可以提高查询效率！推荐只有查询代码的方法中使用
     */
    @Transactional(readOnly=true)
    public void getStudentInfo() {}


    /*
    给子事务设置REQUIRED传播行为，这也是默认值，推荐使用默认值。那么父方法如果有事务，则会把子方法加入到父方法的事务中去。
    子方法报错，那么整个事务会回滚。于是在这里数据修改就不会成功。
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void updateNameById(int id, String name) {
        studentDao.updateNameById(id, name);
    }

    /*
    子方法设置了REQUIRES_NEW事务传播行为，会和父方法的事务互相独立，互相不影响。这里两个子方法都要设置成REQUIRES_NEW
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void updateAgeById(int id, int age) {
        studentDao.updateAgeById(id, age);
        int wrong = 1/0;
    }



}
